import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { TemplateService } from 'src/app/common/providers';

export interface TreeNode {
  key: any;
  parent?: TreeNode;
  level: number;
  expand?: boolean;
  leaf?: boolean;
  children?: TreeNode[];
  [key: string]: any;
}

@Component({
  selector: 'app-tree-table',
  templateUrl: './tree-table.component.html',
  styleUrls: ['./tree-table.component.less'],
})
export class TreeTableComponent implements OnInit {
  // 搜索栏响应式表单
  searchForm: FormGroup;
  // 树形表数据
  treeData: any[];

  constructor(private fb: FormBuilder, private templateServ: TemplateService) {
    this.searchForm = this.fb.group({
      name: [''],
      type: [''],
    });
  }

  ngOnInit(): void {
    // 加载树形表根级数据
    this.templateServ.getTreeData().subscribe((res) => {
      if (res.success) {
        this.treeData = res.data.map((item: TreeNode) => {
          item.key = Symbol();
          item.leaf = false;
          item.level = 0;
          return item;
        });
      }
    });
  }

  /**
   * 展开树节点
   * @param node 树节点
   * @param expand 是否展开
   */
  expandNode(node: TreeNode, expand: boolean): void {
    // 判断是否展开，并且树节点下级节点是否已加载
    if (expand && !Array.isArray(node.children)) {
      this.templateServ.getTreeData().subscribe((res) => {
        if (res.success) {
          // 判断服务端返回下级树节点数据是否为空
          if (Array.isArray(res.data) && res.data.length > 0) {
            // 若下级树节点数据不为空，则挂载在当前树节点上
            node.children = res.data.map((item: TreeNode) => {
              item.key = Symbol();
              item.parent = node;
              item.leaf = false;
              item.level = node.level + 1;
              return item;
            });
          } else {
            // 若下级树节点数据为空，则设置当前树节点为叶节点
            node.leaf = true;
          }
        }
      });
    }
  }

  /**
   * 为当前树节点添加下级
   * @param node 树节点
   */
  addNode(node: TreeNode): void {
    this.templateServ.getTreeNode().subscribe((res) => {
      if (res.success) {
        const child: TreeNode = res.data;
        child.key = Symbol();
        child.level = node.level + 1;
        child.parent = node;
        child.leaf = false;
        node.expand = true;
        // 若当前树节点已有子节点，则直接添加；反之，创建子节点数组
        if (node.children) {
          node.children.push(res.data);
        } else {
          node.children = [res.data];
        }
      }
    });
  }

  /**
   * 编辑当前树节点
   * @param node 树节点
   */
  editNode(node: TreeNode): void {
    this.templateServ.getTreeNode().subscribe((res) => {
      if (res.success) {
        // 使用 Object.assign() 方法合并数据
        node = Object.assign(node, res.data);
      }
    });
  }

  /**
   * 删除当前树节点
   * @param node 树节点
   */
  deleteNode(node: TreeNode): void {
    // 判断是否为根节点
    if (node.parent) {
      node.parent.children = node.parent.children.filter(
        (item) => item.key !== node.key
      );
    } else {
      this.treeData = this.treeData.filter((item) => item.key !== node.key);
    }
  }

  /**
   * 根据树节点的 key 值，查找树节点
   * @param key 树节点的 key 值
   */
  getNodeFromTree(key: any): TreeNode {
    // 使用闭包的方式，递归查找树节点，并返回树节点
    let node: TreeNode = null;
    const getNode = (tree: TreeNode[]) => {
      tree.forEach((item) => {
        if (item.key === key) {
          node = item;
        } else if (Array.isArray(item.children)) {
          getNode(item.children);
        }
      });
    };
    getNode(this.treeData);
    return node;
  }
}
